]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
grabHelper: Port to using ClickGesture to dismiss
authorCarlos Garnacho <carlosg@gnome.org>
Wed, 8 Oct 2025 18:36:39 +0000 (20:36 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Wed, 5 Nov 2025 10:33:55 +0000 (11:33 +0100)
There's a few things we don't need anymore here. We don't
need holding on the captured events until button release
anymore, and we don't need to track crossing events outside
the grab as those will not get emitted as usual. This allows
for a few simplifications in handling the events for the
GrabHelper.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3912>

js/ui/grabHelper.js

index f59766ed901358415ebd71ff05e942708af2e000..9212c168442334dd71f4326220c7ba8c012a78e8 100644 (file)
@@ -29,8 +29,6 @@ export class GrabHelper {
 
         this._grabStack = [];
 
-        this._ignoreUntilRelease = false;
-
         this._modalCount = 0;
     }
 
@@ -162,9 +160,28 @@ export class GrabHelper {
             }
 
             this._grab = grab;
+            this._clickGesture = new Clutter.ClickGesture();
+            this._clickGesture.connect('recognize', () => {
+                const event = this._clickGesture.get_point_event(0);
+                const targetActor = global.stage.get_event_actor(event);
+                if (!this.currentGrab.actor.contains(targetActor)) {
+                    const i = this._actorInGrabStack(targetActor) + 1;
+                    this.ungrab({actor: this._grabStack[i].actor, isUser: true});
+                }
+            });
+            this._owner.add_action(this._clickGesture);
             this._capturedEventId = this._owner.connect('captured-event',
                 (actor, event) => {
-                    return this.onCapturedEvent(event);
+                    const type = event.type();
+
+                    if (type === Clutter.EventType.KEY_PRESS &&
+                        event.get_key_symbol() === Clutter.KEY_Escape) {
+                        this.ungrab({isUser: true});
+                        return Clutter.EVENT_STOP;
+                    }
+
+                    Main.keyboard.maybeHandleEvent(event);
+                    return Clutter.EVENT_PROPAGATE;
                 });
         }
 
@@ -178,7 +195,7 @@ export class GrabHelper {
             return;
 
         this._owner.disconnect(this._capturedEventId);
-        this._ignoreUntilRelease = false;
+        this._owner.remove_action(this._clickGesture);
 
         Main.popModal(this._grab);
         this._grab = null;
@@ -228,56 +245,4 @@ export class GrabHelper {
                 poppedGrab.savedFocus.grab_key_focus();
         }
     }
-
-    onCapturedEvent(event) {
-        const type = event.type();
-
-        if (type === Clutter.EventType.KEY_PRESS &&
-            event.get_key_symbol() === Clutter.KEY_Escape) {
-            this.ungrab({isUser: true});
-            return Clutter.EVENT_STOP;
-        }
-
-        const motion = type === Clutter.EventType.MOTION;
-        const press = type === Clutter.EventType.BUTTON_PRESS;
-        const release = type === Clutter.EventType.BUTTON_RELEASE;
-        const button = press || release;
-
-        const touchUpdate = type === Clutter.EventType.TOUCH_UPDATE;
-        const touchBegin = type === Clutter.EventType.TOUCH_BEGIN;
-        const touchEnd = type === Clutter.EventType.TOUCH_END;
-        const touch = touchUpdate || touchBegin || touchEnd;
-
-        if (touch && !global.display.is_pointer_emulating_sequence(event.get_event_sequence()))
-            return Clutter.EVENT_PROPAGATE;
-
-        if (this._ignoreUntilRelease && (motion || release || touch)) {
-            if (release || touchEnd)
-                this._ignoreUntilRelease = false;
-            return Clutter.EVENT_PROPAGATE;
-        }
-
-        const targetActor = global.stage.get_event_actor(event);
-
-        if (type === Clutter.EventType.ENTER ||
-            type === Clutter.EventType.LEAVE ||
-            this.currentGrab.actor.contains(targetActor))
-            return Clutter.EVENT_PROPAGATE;
-
-        if (Main.keyboard.maybeHandleEvent(event))
-            return Clutter.EVENT_PROPAGATE;
-
-        if (button || touchBegin) {
-            // If we have a press event, ignore the next
-            // motion/release events.
-            if (press || touchBegin)
-                this._ignoreUntilRelease = true;
-
-            const i = this._actorInGrabStack(targetActor) + 1;
-            this.ungrab({actor: this._grabStack[i].actor, isUser: true});
-            return Clutter.EVENT_STOP;
-        }
-
-        return Clutter.EVENT_STOP;
-    }
 }